package com.cskaoyan.mall.pay.service.impl;

import com.cskaoyan.mall.commons.constant.ResponseStatus;
import com.cskaoyan.mall.commons.constant.SysRetCodeConstants;
import com.cskaoyan.mall.commons.exception.BizException;
import com.cskaoyan.mall.commons.result.ServiceCallResponse;
import com.cskaoyan.mall.pay.constants.PayResult;
import com.cskaoyan.mall.pay.constants.PayRetCode;
import com.cskaoyan.mall.pay.dal.entitys.Payment;
import com.cskaoyan.mall.pay.dal.persistence.PaymentMapper;
import com.cskaoyan.mall.pay.form.PaymentRequest;
import com.cskaoyan.mall.pay.remote.OrderApiClient;
import com.cskaoyan.mall.pay.service.PayCoreService;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;

@Slf4j
@Service
@Transactional
public class PayCoreServiceImpl implements PayCoreService {

    @Autowired
    PayHelper payHelper;

    @Autowired
    OrderApiClient orderApiClient;

    @Autowired
    PaymentMapper paymentMapper;

    @Override
    public String aliPay(PaymentRequest request) {
        // 1. 请求支付宝后端，获取支付二维码
        String qrCodeFile = payHelper.test_trade_precreate(request);
        if (qrCodeFile == null) {
            // 获取支付二维码失败，抛出异常
            throw new BizException(PayRetCode.GET_CODE_FALIED.getCode(), PayRetCode.GET_CODE_FALIED.getMsg());
        }

        // 获取支付二维码成功
        // tb_paymen插入一条记录，记录订单的支付信息  TRADE_PROCESSING
        Payment payment = new Payment();
        payment.setStatus(PayResult.TRADE_PROCESSING.getCode());
        payment.setOrderId(request.getOrderId());
        payment.setProductName(request.getInfo());
        payment.setPayerUid(request.getUserId());
        payment.setPayerName(request.getNickName());
        payment.setPayerAmount(request.getMoney());
        payment.setOrderAmount(request.getMoney());
        payment.setPayWay(request.getPayType());
        payment.setCreateTime(new Date());

        try {
            paymentMapper.insertSelective(payment);
        }catch (Exception e) {
            log.info("tb_payment插入新纪录异常");
            throw new BizException(PayRetCode.DB_EXCEPTION.getCode(),
                    PayRetCode.DB_EXCEPTION.getMsg());
        }

        return qrCodeFile;
    }

    @Override
    public boolean queryAlipayRet(String orderId) {

        boolean success = payHelper.test_trade_query(orderId);
        if (success) {
            // 支付成功
            // 1. 修改tb_paymen中，订单的支付状态 TRADE_SUCCESS ，成功时间，完成时间
            Payment payment = new Payment();
            payment.setStatus(PayResult.TRADE_SUCCESS.getCode());

            Date date = new Date();
            payment.setUpdateTime(date);
            payment.setCompleteTime(date);

            Example example = new Example(Payment.class);
            example.createCriteria().andEqualTo("orderId",orderId);
            paymentMapper.updateByExampleSelective(payment,example);

            //  调用订单服务来完成
            // 2. 修改订单的状态 ——> 已支付
            // 3. 查询出订单中的所有商品条目，根据每一个商品条目下单的数量，扣减商品的锁定库存
            ServiceCallResponse serviceCallResponse =
                    orderApiClient.payOrderSuccess(orderId);
            if (!StringUtil.equals(serviceCallResponse.getCode(),SysRetCodeConstants.SERVICE_CALL_SUCCESS.getCode())) {
                throw new BizException(PayRetCode.SERVICE_CALL_PAY_ORDER_FAIL.getCode(),
                        PayRetCode.SERVICE_CALL_PAY_ORDER_FAIL.getMsg());
            }
            return true;
        } else {
            // 支付失败
            // 1.  修改tb_paymen中，订单的支付状态 TRADE_FAILURE， 支付完成时间
            Payment payment = new Payment();
            payment.setStatus(PayResult.TRADE_FAILURE.getCode());
            payment.setCompleteTime(new Date());
            Example example = new Example(Payment.class);
            example.createCriteria().andEqualTo("orderId",orderId);
            paymentMapper.updateByExampleSelective(payment,example);
        }

        return false;
    }
}
